public class AlphaModel extends Model 
{
    /**
     * Das Spielfeld speichert integer, welche einen Charakter repraesentieren; dient dazu nachzuschauen, ob ein Charakter ein Angreifer oder ein Verteidiger ist
     */
    int [][] spielfeld;
    /**
     * Das Charakterfeld speichert die Charaktere im Feld, also sind deren Werte hier nachzuschauen
     */
    Charakter [][] charakterfeld;
    /**
     * schaut, ob ein Feld bebaut ist, oder nicht
     */
    boolean [][] bebaut;
    /**
     * Speichert den Goldstand
     */
    int goldStandSpeicher;
    /**
     * Setzt das Einkommen von Geldsammlern
     */
    int goldSammlerWert;   

    /**
     * Diese Methode erstellt die Ausgangssituation des Spieles
     */
    public AlphaModel(){
        spielfeld = new int[10][6]; //Länge 10, Breite 6
        charakterfeld = new Charakter[10][6];
        bebaut = new boolean [10][6];
        goldStandSpeicher = 100;
        goldSammlerWert = 10;
    }

    /**
     * Diese Methode gibt die Nummer (integer) des Charakters auf dem Spielfeld [Zeile][Spalte]an (Angreifer -1 bis-5 und Türme 0 bis 5)
     * 
     * @param x steht fuer die Zeilen
     * @param y steht fuer die Spalten
     * @return der integer des auf dem Feld stehenden Charakters
     */
    public int inhaltangeben(int x,int y)
    {
        return spielfeld[x][y];
    }

    /**
     * Diese Methode gibt den Charakter auf dem Spielfeld aus
     * 
     * @param x steht fuer die Zeilen
     * @param y steht fuer die Spalten
     * @return Gibt die charakter (Typ: Charakter) zurück
     */
    public Charakter charakterAngeben(int x, int y)
    {
        return charakterfeld [x][y];
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void spielerSetzt(int x, int y, int abwehr)
    /** Spielermethode: Setzt Turm auf Spielfeld[Zeile][Spalte], int abwehr = Nummer des Turms der gesetzt werden soll */
    {
        if(spielfeld[x][y]==0 && bebaut[x][y] == false){
            spielfeld[x][y] = abwehr; 
            bebaut[x][y] = true;

            view.verteidigerFeldSetzen(x,y,abwehr);
            erstellen(x,y,abwehr);

            int kosten = charakterfeld[x][y].costGeben(charakterfeld[x][y]);
            if (goldStandSpeicher >= kosten){ 
                goldstandVeraendern(-kosten); 
            }else{
                sterben(x,y);
                view.kommentarAnzeigen("Geh anschaffen bitch!");
            }
        }else{
            view.kommentarAnzeigen("Dieses Feld ist bereits besetzt!");
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void slown(int x, int y){

        boolean verlangsamt=true;
        if(spielfeld[x][y]<0){
            verlangsamt=charakterfeld[x][y].verlangsamtGeben(charakterfeld[x][y]);
            charakterfeld[x][y].verlangsamtSetzen(verlangsamt);
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ 
    public void entslown(int x, int y){
        boolean verlangsamt=false;
        if(spielfeld[x][y]<0){
            verlangsamt=charakterfeld[x][y].verlangsamtGeben(charakterfeld[x][y]);
            charakterfeld[x][y].verlangsamtSetzen(verlangsamt);
        }        
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void computerSetzt(int y, int angriff)
    /** Computermethode: Setzt Angrifer auf Spielfeld[Zeile][Spalte], int abwehr = Nummer des Turms der gesetzt werden soll */
    {
        int x=8;
        if(spielfeld[x][y]==0 && bebaut[x][y] == false){
            spielfeld[x][y] = angriff; 
            bebaut[x][y] = true;

            view.kommentarAnzeigen("Ein Angreifer ist erschienen!");
            view.angreiferFeldSetzen(x,y,angriff);
            erstellen(x,y,angriff);
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void angreiferBewegen(int x, int y, int angriff,int neueHealth){
        if(spielfeld[x][y]==0){
            spielfeld[x][y] = angriff; 
            bebaut[x][y] = true;
            view.angreiferFeldSetzen(x,y,angriff);
            erstellen(x,y,angriff);
            charakterfeld[x][y].healthSetzen(neueHealth);
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void testMethode(int x, int y, int angriff) //evtl. besserer Name
    /** Computermethode: Gibt die Möglichkeit Angrifer auf alle Felder zu setztn */
    {
        if(spielfeld[x][y]==0 && bebaut[x][y] == false){
            spielfeld[x][y] = angriff; 
            bebaut[x][y] = true;

            view.kommentarAnzeigen("Ein Angreifer ist erschienen!");
            view.angreiferFeldSetzen(x,y,angriff);
        }

    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public boolean spielIstVerloren()
    /** Computermethode: Überprüft ob ein Angrifer das letzte Feld erreicht haben, falls dies eintritt hat der Spieler verloren */
    {   boolean verloren=false;
        for( int i=0;i<5; i++) //Vertikale Prüfung für einen Angreifer
        {
            if(spielfeld[0][i] <0)
            {
                verloren = true;
            }
        } 
        return verloren;
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ 
    public void bewegen(int taktnummer){
        int speed =0;

        for (int i=1;i<10;i++){
            for (int j=0;j<6;j++){
                if(charakterfeld[i][j]!= null && spielfeld[i][j]<0){
                    boolean verlangsamt=charakterfeld[i][j].verlangsamtGeben(charakterfeld[i][j]);
                    if (verlangsamt ==true)
                    {speed = charakterfeld[i][j].speedGeben(charakterfeld[i][j])+1;}
                    else speed = charakterfeld[i][j].speedGeben(charakterfeld[i][j]);
                    if (speed == 2 || speed == 3) 
                    {
                        if (iseven(taktnummer)) {
                                if(spielfeld[i][j]==-2){
                                    if(i==1 && spielfeld[1][j]<=0){
                                        int angreifer= spielfeld [i][j];
                                        spielfeld [i][j]= 0;
                                        bebaut [i][j]= false;

                                        int h = charakterfeld[i][j].healthGeben(charakterfeld[i][j]);
                                        charakterfeld[i][j]=null;

                                        view.hintergrundanPositonSetzten(i,j);
                                        angreiferBewegen(i-1,j,angreifer, h);
                                    }else{
                                        if( i==2 && spielfeld[2][j]<=0 && spielfeld[2][j]<=0){
                                            int angreifer= spielfeld [i][j];
                                            spielfeld [i][j]= 0;
                                            bebaut [i][j]= false;

                                            int h = charakterfeld[i][j].healthGeben(charakterfeld[i][j]);
                                            charakterfeld[i][j]=null;

                                            view.hintergrundanPositonSetzten(i,j);
                                            angreiferBewegen(i-1,j,angreifer, h);

                                        }else{
                                            if(spielfeld[i-3][j]<=0 && spielfeld[i-2][j]<=0 && spielfeld[i-1][j]==0){
                                                int angreifer= spielfeld [i][j];
                                                spielfeld [i][j]= 0;
                                                bebaut [i][j]= false;

                                                int h = charakterfeld[i][j].healthGeben(charakterfeld[i][j]);
                                                charakterfeld[i][j]=null;

                                                view.hintergrundanPositonSetzten(i,j);
                                                angreiferBewegen(i-1,j,angreifer, h);
                                            }else{
                                                angreifenVasall(i,j);
                                            }
                                        }
                                    }
                                }else{
                                    //if(spielfeld[i][j]==-5)
                                    if(spielfeld[i-1][j]==0){
                                        int angreifer= spielfeld [i][j];
                                        spielfeld [i][j]= 0;
                                        bebaut [i][j]= false;

                                        int h = charakterfeld[i][j].healthGeben(charakterfeld[i][j]);
                                        charakterfeld[i][j]=null;

                                        view.hintergrundanPositonSetzten(i,j);
                                        angreiferBewegen(i-1,j,angreifer, h);
                                    }else{
                                        angreifenVasall(i,j);
                                    }
                                }

                            }
                        }
                    }
                }
            }
        }
    

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void angreifenTurm(){
        int damageAngreifender=0;
        int healthAngegriffener=1;
        int angegriffener=0;

        for (int i=0;i<10;i++){
            for (int j=0;j<6;j++){
                angegriffener=i;
                if(i==0){
                    if(charakterfeld[0][j]!=null){
                        if(spielfeld[1][j]<0){
                            sterben(1,j);
                            sterben(0,j);
                            view.hintergrundanPositonSetztenK(j);

                        }
                    }
                }
                if(spielfeld[i][j]>0){
                    if(spielfeld[i][j]==1){ }
                    if(spielfeld[i][j]>1 && spielfeld[i][j]<5){
                        damageAngreifender=charakterfeld[i][j].damageGeben(charakterfeld[i][j]);
                        while(spielfeld[angegriffener][j]>=0 && angegriffener<9){
                            angegriffener=angegriffener+1;
                        }

                        if(spielfeld[angegriffener][j]<0){
                            healthAngegriffener=charakterfeld[angegriffener][j].healthGeben(charakterfeld[angegriffener][j]);
                            healthAngegriffener=healthAngegriffener-damageAngreifender;
                            if(healthAngegriffener>0){
                                charakterfeld[angegriffener][j].healthSetzen(healthAngegriffener);
                            }else{
                                sterben(angegriffener, j);
                            }
                        }

                    }
                    //                        damageAngreifender=charakterfeld[i][j].damageGeben(charakterfeld[i][j]);
                    //                         for(int a=j; spielfeld[i][j]<0; a++){
                    //                             damageAngreifender=charakterfeld[i][j].damageGeben(charakterfeld[i][j]);
                    //                             healthAngegriffener=charakterfeld[i][a].healthGeben(charakterfeld[i][a]);
                    //                             angegriffener=a;
                    //                         }
                    //                         System.out.println("5"+angegriffener);
                    //                         healthAngegriffener=healthAngegriffener-damageAngreifender;
                    //                         if(healthAngegriffener>0){
                    //                             System.out.println("6"+charakterfeld[i][angegriffener]+ "!");
                    //                             charakterfeld[i][angegriffener].healthSetzen(healthAngegriffener);
                    //                         }else{
                    //                             sterben(i, angegriffener);
                    //                         }
                    if(spielfeld[i][j]==5){
                        //                     slown(x+1,y);
                        //                     slown(x,y+1);
                        //                     slown(x,y-1);}
                    }
                }
            }
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void angreifenVasall(int x, int y){
        int damageAngreifender=0;
        int healthAngegriffener=1;
        int angegriffener=0;

        if(spielfeld[x][y]==-2){
            damageAngreifender=charakterfeld[x][y].damageGeben(charakterfeld[x][y]);
            if(spielfeld[x-1][y]>0){
                healthAngegriffener=charakterfeld[x-1][y].healthGeben(charakterfeld[x-1][y]);
                healthAngegriffener=healthAngegriffener-damageAngreifender;
                if(healthAngegriffener>0){
                    charakterfeld[x-1][y].healthSetzen(healthAngegriffener);
                }else{
                    sterben(x-1, y);
                }
            }else{
                if(spielfeld[x-2][y]>0){
                    healthAngegriffener=charakterfeld[x-2][y].healthGeben(charakterfeld[x-2][y]);
                    healthAngegriffener=healthAngegriffener-damageAngreifender;
                    if(healthAngegriffener>0){
                        charakterfeld[x-2][y].healthSetzen(healthAngegriffener);
                    }else{
                        sterben(x-2, y);
                    }
                }else{
                    if(spielfeld[x-3][y]>0){
                        healthAngegriffener=charakterfeld[x-3][y].healthGeben(charakterfeld[x-3][y]);
                        healthAngegriffener=healthAngegriffener-damageAngreifender;
                        if(healthAngegriffener>0){
                            charakterfeld[x-3][y].healthSetzen(healthAngegriffener);
                        }else{
                            sterben(x-3, y);
                        }
                    }
                }
            }
        }else{
            damageAngreifender=charakterfeld[x][y].damageGeben(charakterfeld[x][y]);
            healthAngegriffener=charakterfeld[x-1][y].healthGeben(charakterfeld[x-1][y]);
            healthAngegriffener=healthAngegriffener-damageAngreifender;
            if(healthAngegriffener>0){
                charakterfeld[x-1][y].healthSetzen(healthAngegriffener);
            }else{
                sterben(x-1, y);
            }
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void sterben(int x, int y){
        spielfeld [x][y]= 0;
        bebaut [x][y]= false;
        charakterfeld[x][y]=null;
        // view.lustigeTodesanimation()
        view.hintergrundanPositonSetzten(x,y);
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void erstellen(int x, int y, int charakter){
        if(charakter==0){
            charakterfeld[x][y]= new Kartoffel(x,y);
        }

        if(charakter==1)
        { charakterfeld [x][y] = new Geldsammler(x,y); 

            view.kommentarAnzeigen("Geldsammler gebaut!"); } 

        if(charakter==2){ charakterfeld [x][y] = new Grundverteidiger(x,y);
            view.kommentarAnzeigen("Grundverteidiger gebaut!"); } 

        if(charakter==3){ charakterfeld [x][y] = new Tankverteidiger(x,y);
            view.kommentarAnzeigen("Tankverteidiger gebaut!");}

        if(charakter==4){ charakterfeld [x][y] = new Ninjaverteidiger(x,y);
            view.kommentarAnzeigen("Ninjaverteidiger gebaut!");}

        if(charakter==5){ charakterfeld [x][y] = new Verlangsamerungsverteidiger(x,y);
            view.kommentarAnzeigen("Verlangsamerungsverteidiger gebaut!");}

        if(charakter==-1){ charakterfeld [x][y] = new Grundvasall(x,y);
            view.kommentarAnzeigen("Grundvasall gebaut!");}

        if(charakter==-2){ charakterfeld [x][y] = new Fernkampfvasall(x,y);}
        if(charakter==-3){ charakterfeld [x][y] = new Fernkampfvasall(x,y);}
        if(charakter==-4){ charakterfeld [x][y] = new Tankvasall(x,y);}
        if(charakter==-5){ charakterfeld [x][y] = new Bossvasall(x,y);}

    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void goldstandVeraendern(int goldVeraendern)
    {
        /** goldstandVeraendern("Veränderung")berechnet den neuen Goldstand.
         * Eingabemöglichkeiten für Variable(int goldVeraendern): +Zahl(kein Vorzeichen nötig) oder -Zahl 
         */
        if (goldStandSpeicher+goldVeraendern >= 0)
        {
            goldStandSpeicher = goldStandSpeicher+goldVeraendern;
            String gold = Integer.toString(goldStandSpeicher);       //Konvertierung von int in String (wichtig für JLabel)
            view.goldAnzeigen(gold);                                 //Anzeige auf JLabel Anzeige: gold + $
            view.kommentarAnzeigen("Veränderung des Goldstands");
            System.out.println("Gold:"+goldStandSpeicher+"Veränderung von:"+goldVeraendern);

        } else {
            System.out.println("Gold kann nicht negativ werden");
        }
    }

    /**
     * Diese Methode. 
     * 
     * @param x
     * @param y 
     * @return
     */ public void goldSammeln()    
    {   
        /** goldSammelen()
         * Sucht das Spielfeld [][] nach Gold/Geldsammlern ab und
         * führt dann goldstandVeraendern("festgelegtes Einkommen"*die aktiven Goldsammler) aus.
         */
        int goldSammlerAktiv = 0;
        for (int i=0; i<8;i++)
        {
            for (int j=0; j<6;j++) 
            {
                if (spielfeld [i][j] == 1 )
                {
                    goldSammlerAktiv=goldSammlerAktiv+1;
                    System.out.println("Sammler gefunden:"+goldSammlerAktiv);
                } 
            }
        }
        goldstandVeraendern((goldSammlerWert*goldSammlerAktiv));     
    }


    /** Computermethode: Bewegt alle Angrifer ein Feld nach links */
    public boolean iseven(int zahl)
    {
        return (zahl%2==0);
    }
}
